package com.snack.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.snack.shop.entity.FileRecord;
import com.snack.shop.mapper.FileRecordMapper;
import com.snack.shop.service.FileManageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 文件管理服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FileManageServiceImpl implements FileManageService {

    private final FileRecordMapper fileRecordMapper;

    @Value("${file.upload.path:/tmp/uploads}")
    private String uploadPath;

    @Value("${file.upload.url-prefix:http://localhost:8080/api/uploads}")
    private String urlPrefix;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long recordUpload(String fileName, String filePath, String fileUrl, Long fileSize,
                            String module, String uploadDate, Long uploaderId) {
        FileRecord record = new FileRecord();
        record.setFileName(fileName);
        record.setFilePath(filePath);
        record.setFileUrl(fileUrl);
        record.setFileSize(fileSize);
        record.setModule(module);
        record.setUploadDate(uploadDate);
        record.setStatus(0); // 临时状态
        record.setUploaderId(uploaderId);
        
        fileRecordMapper.insert(record);
        log.info("记录文件上传: {} -> {}", fileName, fileUrl);
        
        return record.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmFiles(List<String> fileUrls, String refType, Long refId) {
        if (fileUrls == null || fileUrls.isEmpty()) {
            return;
        }

        LambdaQueryWrapper<FileRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(FileRecord::getFileUrl, fileUrls)
               .eq(FileRecord::getDeleted, 0);

        List<FileRecord> records = fileRecordMapper.selectList(wrapper);
        
        for (FileRecord record : records) {
            record.setStatus(1); // 正式状态
            record.setRefType(refType);
            record.setRefId(refId);
            fileRecordMapper.updateById(record);
        }

        log.info("确认文件为正式状态: {} 个文件，关联业务: {}:{}", records.size(), refType, refId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markDeleted(List<String> fileUrls) {
        if (fileUrls == null || fileUrls.isEmpty()) {
            return;
        }

        LambdaQueryWrapper<FileRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(FileRecord::getFileUrl, fileUrls)
               .eq(FileRecord::getDeleted, 0);

        List<FileRecord> records = fileRecordMapper.selectList(wrapper);
        
        for (FileRecord record : records) {
            record.setStatus(2); // 已删除状态
            fileRecordMapper.updateById(record);
        }

        log.info("标记文件为已删除: {} 个文件", records.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cleanTemporaryFiles(int days) {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(days);

        LambdaQueryWrapper<FileRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FileRecord::getStatus, 0) // 临时状态
               .eq(FileRecord::getDeleted, 0)
               .lt(FileRecord::getCreateTime, expireTime);

        List<FileRecord> expiredFiles = fileRecordMapper.selectList(wrapper);
        
        int deletedCount = 0;
        for (FileRecord record : expiredFiles) {
            // 物理删除文件
            if (deletePhysicalFile(record.getFileUrl())) {
                // 逻辑删除记录
                record.setDeleted(1);
                fileRecordMapper.updateById(record);
                deletedCount++;
            }
        }

        log.info("清理临时文件: 扫描 {} 个，成功删除 {} 个", expiredFiles.size(), deletedCount);
        return deletedCount;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cleanDeletedFiles(int days) {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(days);

        LambdaQueryWrapper<FileRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FileRecord::getStatus, 2) // 已删除状态
               .eq(FileRecord::getDeleted, 0)
               .lt(FileRecord::getUpdateTime, expireTime);

        List<FileRecord> expiredFiles = fileRecordMapper.selectList(wrapper);
        
        int deletedCount = 0;
        for (FileRecord record : expiredFiles) {
            // 物理删除文件
            if (deletePhysicalFile(record.getFileUrl())) {
                // 逻辑删除记录
                record.setDeleted(1);
                fileRecordMapper.updateById(record);
                deletedCount++;
            }
        }

        log.info("清理已删除文件: 扫描 {} 个，成功删除 {} 个", expiredFiles.size(), deletedCount);
        return deletedCount;
    }

    @Override
    public boolean deletePhysicalFile(String fileUrl) {
        try {
            // 从URL提取相对路径
            String relativePath = fileUrl.replace(urlPrefix + "/", "");
            
            // 构建完整文件路径
            File baseUploadDir = new File(uploadPath);
            if (!baseUploadDir.isAbsolute()) {
                baseUploadDir = new File(System.getProperty("user.dir"), uploadPath);
            }
            
            File file = new File(baseUploadDir, relativePath);
            
            if (file.exists() && file.isFile()) {
                boolean deleted = file.delete();
                if (deleted) {
                    log.info("物理删除文件成功: {}", file.getAbsolutePath());
                    
                    // 尝试删除空目录
                    deleteEmptyDirectories(file.getParentFile(), baseUploadDir);
                } else {
                    log.warn("物理删除文件失败: {}", file.getAbsolutePath());
                }
                return deleted;
            } else {
                log.warn("文件不存在或不是文件: {}", file.getAbsolutePath());
                return true; // 文件不存在也视为删除成功
            }
        } catch (Exception e) {
            log.error("删除文件失败: {}", fileUrl, e);
            return false;
        }
    }

    /**
     * 递归删除空目录
     */
    private void deleteEmptyDirectories(File dir, File baseDir) {
        if (dir == null || !dir.exists() || !dir.isDirectory()) {
            return;
        }

        // 不要删除基础目录
        if (dir.getAbsolutePath().equals(baseDir.getAbsolutePath())) {
            return;
        }

        // 检查目录是否为空
        String[] files = dir.list();
        if (files != null && files.length == 0) {
            if (dir.delete()) {
                log.info("删除空目录: {}", dir.getAbsolutePath());
                // 递归检查父目录
                deleteEmptyDirectories(dir.getParentFile(), baseDir);
            }
        }
    }
}

